/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-06-03     jerry       the first version
 */
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-05-11     tt       the first version
 */

#include <rtthread.h>

#define SAMPLE_UART_NAME       "uart5"      /* 串口设备名称 */
//struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 初始化配置参数 */
#define UART_DEBUG 1

/* 串口接收消息结构*/
struct rx_msg
{
    rt_device_t dev;
    rt_size_t size;
};

rt_bool_t inited = 0;
rt_atomic_t reject_input = 0;
/* 串口设备句柄 */
static rt_device_t serial;
/* 消息队列控制块 */
static struct rt_messagequeue rx_mq;

/* 接收数据回调函数 */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
    if (rt_atomic_load(&reject_input))
    {
        return RT_EOK;
    }
    struct rx_msg msg;
    rt_err_t result;
    msg.dev = dev;
    msg.size = size;

    result = rt_mq_send(&rx_mq, &msg, sizeof(msg));
    if (result == -RT_EFULL)
    {
        /* 消息队列满 */
        rt_kprintf("message queue full！\n");
    }
    return result;
}
int uart_dma_sample();
void open_uart()
{

    if (!inited)
    {
        uart_dma_sample();
        inited = 1;
    }
    struct rx_msg msg;
    // 清空队列
    while (rt_mq_recv(&rx_mq, &msg, sizeof(msg), 1) > 0)
    {
        rt_kprintf("recv...\n");
        continue;
    }
    rt_atomic_store(&reject_input, 0);
}
void close_uart()
{
}

size_t ptc06_read_image(uint8_t** buf, int length)
{
    if (!inited)
    {
        uart_dma_sample();
        inited = 1;
    }
    struct rx_msg msg;
    rt_memset(&msg, 0, sizeof(msg));
    rt_uint32_t rx_length = 0;
    rt_ssize_t result = rt_mq_recv(&rx_mq, &msg,
            sizeof(msg), RT_WAITING_FOREVER);
    uint8_t* rx_buffer = *buf;
    rt_memset(rx_buffer, 0, length);
    RT_ASSERT(rx_buffer);
    while (result > 0)
    {
        /* 从串口读取数据*/
        if (!(rx_length + msg.size <= length))
        {
            rt_kprintf("i:%d,size:%d,length:%d", rx_length,
                    msg.size, length);
        }
        int increase = rt_device_read(msg.dev, 0, rx_buffer,
                msg.size);
        if (increase > msg.size)
        {
            return 0;
        }
        rx_length += increase;
        rx_buffer += increase;
        if (rx_length < length)
        {
            rt_kprintf("next\n");
            result = rt_mq_recv(&rx_mq, &msg, sizeof(msg),
            RT_WAITING_FOREVER);
        }
        else
        {
            result = 0;
        }
    }
    return rx_length;
}

size_t ptc06_read(uint8_t** buf)
{
    if (!inited)
    {
        uart_dma_sample();
        inited = 1;
    }
    struct rx_msg msg;
    rt_memset(&msg, 0, sizeof(msg));
    rt_uint32_t rx_length = 0;
    rt_ssize_t result = rt_mq_recv(&rx_mq, &msg,
            sizeof(msg), RT_WAITING_FOREVER);
    if (result > 0)
    {
        uint8_t* rx_buffer = (uint8_t*) rt_malloc(
                msg.size + 1);
        if (rx_buffer == NULL)
        {
            rt_kprintf("malloc fail！\n");
            return 0;
        }

        rt_memset(rx_buffer, 0, msg.size);
        /* 从串口读取数据*/
        rx_length = rt_device_read(msg.dev, 0, rx_buffer,
                msg.size);
        *buf = rx_buffer;
    }
#ifdef UART_DEBUG
    for (int i = 0; i < rx_length; i++)
    {
        rt_kprintf("%02x ", (*buf)[i]);
    }
    rt_kprintf("\n");
#endif
    return rx_length;
}
int ptc06_write(uint8_t* buf, size_t len)
{
    if (!inited)
    {
        uart_dma_sample();
        inited = 1;
    }
    if (rt_device_write(serial, 0, buf, len) == 0)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int uart_dma_sample()
{
    rt_err_t ret = RT_EOK;
    char uart_name[RT_NAME_MAX];
    static char msg_pool[256];

    rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);

    /* 查找串口设备 */
    serial = rt_device_find(uart_name);
    if (!serial)
    {
        rt_kprintf("find %s failed!\n", uart_name);
        return RT_ERROR;
    }

    /* 初始化消息队列 */
    rt_mq_init(&rx_mq, "rx_mq", msg_pool, /* 存放消息的缓冲区 */
    sizeof(struct rx_msg), /* 一条消息的最大长度 */
    sizeof(msg_pool), /* 存放消息的缓冲区大小 */
    RT_IPC_FLAG_FIFO); /* 如果有多个线程等待，按照先来先得到的方法分配消息 */

//    config.bufsz = 100 << 10;
//    rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);
    /* 以 DMA 接收及轮询发送方式打开串口设备 */
    rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(serial, uart_input);
    /* 发送字符串 */
//    rt_device_write(serial, 0, str, (sizeof(str) - 1));
    rt_kprintf("uart init success\n");
    return ret;
}

//INIT_ENV_EXPORT(uart_dma_sample);
